<?php
class DevAction extends ZMAction {
    public function tree(){
        $Model = M('Dev');
        $devid = $_REQUEST['node'];
        $map['parentid'] = $devid;
        $map['isattr'] = 0;//不在树状中显示属于属性的节点
        $map['istemp'] = 0;
        $result = $Model->where($map)->select();
        if($result){
            foreach($result as &$item){
                $item['id'] = $item['devid'];
                $item['text'] = $item['devname'];
                $item['cls'] = 'group';
                $childNodes = $Model->where("parentid='". $item['devid']."'")->count();
                if(empty($childNodes)){
                    $item['leaf'] = true;
                }else{
                    $item['expanded'] = false;
                }
            }
        }else{
            $result = array();
        }     
        echo(json_encode($result));  
    }
    
    /**
    * 获取设备属性列表
    * 
    * @param mixed $devid
    */
    public function getDevAttr($devid){
        $ModelDev = M('Dev');
        $ModelEnum = M('ValTypeComboEnum');
        $ModelAttrDef = M('DevAttrDef');
        
        $where['devid'] = $devid;
        $resDev = $ModelDev->where($where)->find();
        if($resDev){
            $ddid = $resDev['ddid'];
            $result = $ModelAttrDef->where("ddid=$ddid")->select();
            foreach($result as &$row){
                $row['ddevid'] = $devid;
                $resAttr = $this->getValue($row['vtid'],$row['defval']);
                $resDevAttr = $this->getDevAttrVal($devid,$row['attrid']);
                if($resAttr){
                    $row['editor'] = $resAttr['editor'];
                    if($resAttr['editor'] == 'devfield'){ //递归的
                        $resDevSub = false; //假设没有设备属性创建
                        if($resDevAttr){ 
                            $row['devid'] = $resDevAttr['value'];
                            $resDevSub = $ModelDev->where('devid='.$row['devid'])->find();
                        }
                        if($resDevSub === false){  //设备属性未存在,需要新创建
                            if(empty($row['devid'])){
                                $resDevSub = $this->createDev($devid,$resAttr['value'],$row['attrname'],$resDev['istemp'],1);
                            }else{
                                $resDevSub = $this->cloneDev($devid,$row['devid'],$row['attrname'],$resDev['istemp'],1);
                            }
                            if($resDevSub){
                                $this->setDevAttrValue($devid,$resAttr['attrid'],$resDevSub);//修改属性值
                            }
                        }
                        if($resDevSub){
                            $row['defval'] = $resDevSub['ddid'];
                            $row['valdesc'] = $resDevSub['devname'];
                        }
                        
                        $childrens = $this->getDevAttr($row['devid']);
                        if($childrens){
                            $row['children'] = $childrens;
                            $row['expanded'] = false;
                        }else{
                            $row['leaf'] = true;
                        }
                    }else if($row['editor'] == 'combo'){
                        if($resDevAttr){
                            $row['defval'] = $resDevAttr['value'];
                        }
                        if(!is_null($row['defval'])){
                            $map['vtid'] = $row['vtid'];
                            $map['id'] = $row['defval'];
                            $res = $ModelEnum->where($map)->find();
                            if($res){
                                $row['valdesc'] = $res['val'];
                            }
                        }
                        $row['leaf'] = true;
                    }else{
                        if($resDevAttr){
                            $row['defval'] = $resDevAttr['value'];
                            $row['valdesc'] = $resDevAttr['value'];
                            $row['vval'] = $resDevAttr['vval'];
                        }else{
                            $row['valdesc'] = $resAttr['value'];
                        }
                        $row['leaf'] = true;
                    }                
                }
                $row['iconCls'] = 'mattr';
            }
            return $result;
        }
        return null;
    }
    
    /**
    * 获取属性
    * 
    */
    public function getAttr(){
        $devid = $_REQUEST['devid'];
        $ModelDev = M('Dev');
        $where['devid'] = $devid;
        $resDev = $ModelDev->where($where)->find();
        if($resDev){
            $ret = $this->getDevAttr($devid);
            
            if($ret){
                foreach($ret as &$row){
                    $row['devname'] = $resDev['devname'];
                    break;
                }
            }
            
            echo json_encode($ret);
        }else{
            echo '';
        }
    }
    
    /**
    * 设置属性值
    * 
    */
    public function setAttr(){
        $devid = $_REQUEST['devid'];
        $attrid = $_REQUEST['attrid'];
        $val = $_REQUEST['val'];
        $this->setDevAttrValue($devid,$attrid,$val);
        
        $modelAttrDef = M('DevAttrDef');
        $resDef = $modelAttrDef->where("attrid=$attrid")->find();
        if($resDef){
            if($resDef['attrname'] == '机架位置'){
                $x = 0.07;
                $y = 0.1 + ($val - 1) * 0.04445;
                $z = -0.09;
                $this->setDevXYZ($devid,$x,$y,$z);
                $retTrans = $this->getDevTransform($devid);
                if($retTrans){
                    $this->ajaxReturn($retTrans,'ok',true);
                    return;
                }    
            }
        }
        
        //判断修改的是否空间坐标
        $modelDev = M('Dev');
        $resDev = $modelDev->where("devid=$devid")->find();
        if($resDev){
            if($resDev['ddid'] == C('XYZ')){ //修改的是空间坐标，需要返回
                $retTrans = $this->getDevTransform($resDev['parentid']); //需要获取的是父级的设备变换，因为空间坐标是以子节点的形式存在的
                if($retTrans){
                    $this->ajaxReturn($retTrans,'ok',true);
                    return;
                }    
            }
        }
        
        $this->ajaxReturn(null,'ok',true);
    }
    
    /**
    * 克隆一个设备
    * 
    * @param mixed $parentid 设备所属上级
    * @param mixed $devid    待克隆的设备
    * @param mixed $devname  克隆出的设备名称
    * @param mixed $istemp   是否作为模版
    */
    public function cloneDev($parentid,$devid,$devname,$istemp=0,$isattr=0){
        $ModelDev = M('Dev');
        $resDev = $ModelDev->where("devid=$devid")->find();
        if($resDev){
            $data['devname'] = $devname;
            $data['ddid'] = $resDev['ddid'];
            $data['parentid'] = $parentid;
            $data['istemp'] =  $istemp;
            $data['isattr'] = $isattr;
            $newDevid = $ModelDev->add($data);
             
            $ModelDevAttr = M('DevAttr');   
            $resDevAttr = $ModelDevAttr->where("devid=$devid")->select();
            foreach($resDevAttr as $row){
                $resAttr = $this->getAttrVal($row['attrid'],$row['val']);
                if($resAttr){
                    if($resAttr['editor']=='devfield'){
                        $val = $this->cloneDev($newDevid,$resAttr['value'],$resAttr['attrname'],$istemp,1);
                        $this->setDevAttrValue($newDevid,$row['attrid'],$val);
                    }else{
                        $this->setDevAttrValue($newDevid,$row['attrid'],$resAttr['value']);                        
                    }
                }    
            }
            return $newDevid;
        }
        return false;
    }
    
    /**
    * 根据模版定义创建一个新的设备
    * 
    * @param mixed $ddid    模版id
    * @param mixed $devname 新设备名称
    * @return   新设备
    */
    public function createDev($parentid,$ddid,$devname,$istemp=0,$isattr=0){
        $ModelDevDef = M('DevDef');
        $ModelDevAttrDef =  M('DevAttrDef');
        $resDevDef = $ModelDevDef->where("ddid=$ddid")->find();
        if($resDevDef){
            $ModelDev = M('Dev');
            $ModelDevAttr = M('DevAttr');         
            $data['devname'] = $devname;
            $data['ddid'] = $ddid;
            $data['parentid'] = $parentid;
            $data['istemp'] = $istemp;
            $data['isattr'] = $isattr;
            $devid = $ModelDev->add($data);
            if($devid !== false){
                $bSucc = true;
                $resDevAttr = $ModelDevAttrDef->where("ddid=$ddid")->select();
                foreach($resDevAttr as $row){
                    $resAttr = $this->getAttrVal($row['attrid'],$row['defval']);
                    if($resAttr){
                        if($resAttr['editor']=='devfield'){
                            if(empty($row['devid'])){
                                $val = $this->createDev($devid,$resAttr['value'],$resAttr['attrname'],$istemp,1);
                            }else{
                                $val = $this->cloneDev($devid,$row['devid'],$row['attrname'],$istemp,1);
                            }
                            $this->setDevAttrValue($devid,$row['attrid'],$val);
                        }else{
                            $this->setDevAttrValue($devid,$row['attrid'],$resAttr['value']);
                        }
                    }
                }
            }
            return $devid;
        }
        return false;
    }
    
    protected function getX3dInfo($devid){
        $model = M('Dev');
        $resDev = $model->where("devid=$devid")->find();
        if($resDev){
            $ret = array();
            $ret['devid'] = $devid;
            $ret['parentid'] = $resDev['parentid'];
            $ret['devname'] = $resDev['devname'];
            $ret['transform'] = $this->getDevTransform($devid);
            $ret['modelurl'] = $this->getModelUrl($resDev['ddid']);

            $ret['children'] = array();
            $childDev = $model->where("parentid=$devid")->select();
            foreach($childDev as $dev){
                $ret['children'][] = $this->getX3dInfo($dev['devid']);
            }
            return $ret;
        }else{
            return null;
        }
    }
    
    /**
    * 添加设备
    * 
    */
    public function add(){
        $parentid = $_REQUEST['parentid'];
        $ddid = $_REQUEST['ddid'];
        $devname = $_REQUEST['devname'];
        $Model = M('Dev');
        $Model->startTrans();
        $devid = $this->createDev($parentid,$ddid,$devname);
        if($devid === false){
            $Model->rollback;
            $this->error('fail');
        }else{
            $Model->commit();
            //返回设备必要信息，以备生成X3D
            $ret = $this->getX3dInfo($devid);
            
            $this->ajaxReturn($ret,'success',true);
        }
    }
    
    /**
    * 从数据库中删除
    * 
    * @param mixed $devid
    */
    public function delDev($devid){
        $ModelDev = M('Dev');
        $Model = M('DevAttr');
        
        $where['devid'] = $devid;
        $result = $Model->where($where)->select();
        foreach($result as $row){
            $resAttr = $this->getAttrVal($row['attrid'],$row['val']);
            if($resAttr){
                if($resAttr['editor'] == 'devfield'){ //递归的
                    $this->delDev($resAttr['value']);
                }
                $this->delValue($resAttr['vtid'],$row['val']);
            }
            $Model->where('id='.$row['id'])->delete();
        }
        $ModelDev->where("devid=$devid")->delete();
    }
    
    /**
    * 删除设备
    * 
    */
    public function del(){
        $devid = $_REQUEST['devid'];
        $this->delDev($devid);
        $this->success('ok');
    }
    
    /**
    * 更改设备名称
    * 
    */
    public function renName(){
        $devid = $_REQUEST['devid'];
        $devname = $_REQUEST['devname'];
        
        $ModelDev = M('Dev');    
        $data['devname'] = $devname;
        $ModelDev->where("devid=$devid")->save($data);
        $this->success('ok');
    }
    
    protected function updateDevIsAttr($devid){
        //排除属性的子节点
        $Model = M('Dev');
        $dev = $Model->where("devid=$devid")->find();
        if($dev){
            $ddid = $dev['ddid'];
            //从属性定义表中查询属于'devfield'的字段
            $modelAttr = D('AttrDefView');
            $map['ddid'] = $ddid;
            $map['editor'] = 'devfield';
            $sqlAttrId = $modelAttr->field('attrid')->where($map)->select(false);
            $modelDevAttr = M('DevAttr');
            $where['devid'] = $devid;
            $where['_string'] = " attrid in $sqlAttrId";
            $sqlVal = $modelDevAttr->field('val')->where($where)->select(false);
            $modelVal = M('ValNum');
            $subQuery = $modelVal->field('val')->where("id in $sqlVal")->select(false);
        }
        
        unset($map);
        $map['parentid'] = $devid;
        $map['istemp'] = 0;
        if(!empty($subQuery)) $map['_string'] = " devid in $subQuery";

        $data['isattr'] = 1;
        $Model->where($map)->save($data);
        
        if(!empty($subQuery)) $map['_string'] = " devid not in $subQuery";
        $subDev = $Model->where($map)->select();
        foreach($subDev as $row){
            $this->updateDevIsAttr($row['devid']);
        }
    }
    
    public function test(){
        $this->updateDevIsAttr(0);
    }
}